# 从 flask 包中导入 Flask 类
# request 可以理解为整个 Flask 项目的唯一全局变量
# render_template 是一个函数
from datetime import datetime
from typing import Any
from flask_sqlalchemy import SQLAlchemy  # ORM框架(Object Relationship Mapping)
from flask import Flask, request, render_template

# 创建 Flask 对象
# __name__: 代表当前app.py这个模块
# 1. 帮助我们快速定位 bug
# 2. 对于寻找模板文件，有一个相对路径
from sqlalchemy import CursorResult, text

app: Flask = Flask(__name__)

HOSTNAME = "127.0.0.1"
PORT = 3306
USERNAME = "root"
PASSWORD = "Yan1029."
DATABASE = "flask_study"

app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"

db: SQLAlchemy = SQLAlchemy(app)

# 测试数据库是否连接成功
with app.app_context():
    with db.engine.connect() as conn:
        rs: CursorResult[Any] = conn.execute(text("select 1"))
        print(rs.fetchone())


class User:
    # python 中的成员变量不需要专门去显式声明，而是直接在构造方法中使用即可
    def __init__(self, username: str, password: str):
        self.username = username
        self.password = password


# 创建一个路由和视图函数的映射
# http 用的都是 80 端口，https 用的都是 443 端口
# 浏览器在访问域名时会自动把域名转为ip地址拼上协议对应的端口
@app.route('/')
def hello_world():
    user = User("lyh", "123456")
    person = {
        "username": "李大喜",
        "password": "123456"
    }
    books = [{
        "name": "《牛虻》",
        "author": "艾捷尔·丽莲·伏尼契",
        "price": 28.98
    }, {
        "name": "《平凡的世界》",
        "author": "路遥",
        "price": 38.8
    }]
    return render_template("index.html", user=user, person=person, books=books)  # 使用 render_template 函数


@app.route('/blog/<int:blog_id>')  # 定义参数类型 string/int/float/path/uuid/any
def search(blog_id: int):
    print('这是第 %d 篇博客' % blog_id)
    return render_template("blog_detail.html", blog_id=blog_id)  # 传递参数给html


@app.route('/book/list')
def book_list():
    # args 是一个字典类型
    page = request.args.get('page', default=1, type=int)  # /book/list?page=2
    return f'请求了第 {page} 页的数据'


@app.route("/filter")
def filter_demo():
    user = User(username="燕双鹰", password="123123")
    return render_template("filter.html", user=user, now=datetime.now())


# 自定义过滤器
def date_format(value: datetime, format="%Y年-%d月-%m日 %H:%M"):
    return value.strftime(format)


# 添加过滤器到渲染模板
app.add_template_filter(date_format, "d_format")  # 1.自定义函数 2.函数名称


# 继承父模板
@app.route("/child")
def child1():
    return render_template("child.html")


# 如果当前程序作为一个主入口程序来运行
if __name__ == '__main__':
    # 开启 debug 模式(1. 相当于开启热加载 2. 报错可以直接打印到网页)
    # 当host=0.0.0.0 或者为本地ip地址时(ipconfig|ifconfig)，同一局域网下的其他设备都可以访问该地址
    app.run(debug=True, host='0.0.0.0', port=8000)

